﻿#pragma once
#include "collection/ArrayList.hpp"
#include "yzrutil.h"
#include "SimpleDSP.h"
#include <vector>
namespace yzrilyzr_dsp{
	class DSP;
}
namespace yzrilyzr_interpolator{
	class Interpolator;
}

namespace yzrilyzr_util{
	namespace ParamType{
		constexpr int Sub=-1;
		constexpr int Float=0;
		constexpr int Double=1;
		constexpr int Int=2;
		constexpr int UInt=3;
		constexpr int Long=4;
		constexpr int ULong=5;
		constexpr int Bool=6;
		constexpr int Size=7;
		constexpr int Enum=10;
		//
		constexpr int Freq=20;
		constexpr int Time=30;
		constexpr int TimeMs=31;
		constexpr int Sample=32;
		constexpr int Gain=33;
		//
		constexpr int Interpolator=50;
		constexpr int DSP=51;
	}
	struct ParamReg{
		int type=0;
		yzrilyzr_lang::String name;
		yzrilyzr_lang::String aliasName;
		void * value=nullptr;
		void * valueMin=nullptr;
		void * valueMax=nullptr;
	};
	EBCLASS(ParamRegister){
		public:
		std::vector<ParamReg> RegisteredParams;
		virtual ~ParamRegister(){}
		void registerParamNormal01(const yzrilyzr_lang::String & name, u_normal_01 * value){
			static double min=0, max=1;
			registerParam(name, ParamType::Double, value, &min, &max);
		}
		void registerParamNormal11(const yzrilyzr_lang::String & name, u_normal_11 * value){
			static double min=-1, max=1;
			registerParam(name, ParamType::Double, value, &min, &max);
		}
		void registerParamFreq(const yzrilyzr_lang::String & name, u_freq * value){
			static double min=1, max=20000;
			registerParam(name, ParamType::Freq, value, &min, &max);
		}
		void registerParamInterpolator(const yzrilyzr_lang::String & name, std::shared_ptr<yzrilyzr_interpolator::Interpolator> *value){
			registerParam(name, ParamType::Interpolator, value, nullptr, nullptr);
		}
		void registerParamGain(const yzrilyzr_lang::String & name, u_sample * value){
			static u_sample min=0.0, max=10.0;
			registerParam(name, ParamType::Gain, value, &min, &max);
		}
		void registerParamSample(const yzrilyzr_lang::String & name, u_sample * value){
			static u_sample min=0.0, max=10.0;
			registerParam(name, ParamType::Sample, value, &min, &max);
		}
		void registerParamDSP(const yzrilyzr_lang::String & name, std::shared_ptr <yzrilyzr_dsp::DSP> *value){
			registerParam(name, ParamType::DSP, value, nullptr, nullptr);
		}
		void registerParamBool(const yzrilyzr_lang::String & name, bool * value){
			registerParam(name, ParamType::Bool, value, nullptr, nullptr);
		}
		void registerParamTime(const yzrilyzr_lang::String & name, u_time * value){
			static double min=0, max=10;
			registerParam(name, ParamType::Time, value, &min, &max);
		}
		void registerParamTimeMs(const yzrilyzr_lang::String & name, u_time_ms * value){
			static double min=0, max=10000;
			registerParam(name, ParamType::TimeMs, value, &min, &max);
		}
		void registerParamEnum(const yzrilyzr_lang::String & name, int * value, const char ** enumNames, int enumCount){
			static int max=enumCount;
			registerParam(name, ParamType::Enum, value, enumNames, &max);
		}
		void registerParamAlias(const yzrilyzr_lang::String & orgName, const yzrilyzr_lang::String & aliasName){
			for(auto & p : RegisteredParams){
				if(p.name == orgName){
					p.aliasName=aliasName;
				}
			}
		}
		void registerSub(const yzrilyzr_lang::String & name, yzrilyzr_util::ParamRegister * sub){
			registerParam(name, ParamType::Sub, sub, nullptr, nullptr);
		}
		void registerParam(const yzrilyzr_lang::String & name, int type, void * value, void * valueMin, void * valueMax){
			ParamReg param;
			param.name=name;
			param.aliasName="";
			param.type=type;
			param.value=value;
			param.valueMin=valueMin;
			param.valueMax=valueMax;
			RegisteredParams.push_back(param);
		}
	};
}